package main

import (
	"crypto/tls"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"strings"
	"time"
)

type myRequest struct {
	ssl    bool
	method string
	url    string
	header *map[string]string
	data   string
	cookie []*http.Cookie
}

type signStatus struct {
	IsSign        bool   `json:"isSign"`
	IsQueryDomain bool   `json:"isQuserDomain"`
	Core          int    `json:"core"`
	Date          string `json:"date"`
}

func (req *myRequest) send() (resp *http.Response, err error) {
	client := http.Client{}
	if req.ssl {
		tr := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
		client.Transport = tr
	}
	request, _ := http.NewRequest(req.method, req.url, strings.NewReader(req.data))
	if req.cookie != nil {
		for _, cookie := range req.cookie {
			request.AddCookie(cookie)
		}
	}
	if req.header != nil {
		for key, value := range *req.header {
			request.Header.Set(key, value)
		}
	}
	resp, err = client.Do(request)
	return
}

func main() {
	questTag := `
			# 0 = 没有安全提问
			# 1 = 母亲的名字
			# 2 = 爷爷的名字
			# 3 = 父亲出生的城市
			# 4 = 您其中一位老师的名字
			# 5 = 您个人计算机的型号
			# 6 = 您最喜欢的餐馆名称
			# 7 = 驾驶执照的最后四位数字`
	Username := flag.String("u", "", "Login username not empty")
	Password := flag.String("p", "", "Login password md5 not empty")
	QuestionNum := flag.Int("q", 0, fmt.Sprintf("Question type num:%s", questTag))
	QuestionAnswer := flag.String("a", "", "question answer")
	flagPath := flag.String("f", "tubi", "Sign flag file")
	secret := flag.String("secret", "", "ding secret")
	accessToken := flag.String("token", "", "ding access_token")
	queryDomain := flag.Bool("d", false, "query domain flag")
	flag.Parse()
	if *Username == "" || *Password == "" {
		flag.Usage()
		os.Exit(-1)
	}
	times := time.Now().Add(time.Hour * 8) //东八区
	//currentData := fmt.Sprintf("%v-%v-%v", times.Year(), times.Month(), times.Day())
	currentData := strings.Split(times.String(), " ")[0]
	var msg []string
	status := signStatus{}
	fileDate, err := ioutil.ReadFile(*flagPath)
	if err != nil {
		msg = append(msg, "tubi 文件不存在，可能是第一次运行此程序。")
	} else {
		err = json.Unmarshal(fileDate, &status)
		if err != nil {
			var errOut any
			errOut = err.Error()
			panic(errOut)
		}
	}
	if strings.Contains(currentData, status.Date) {
		if !*queryDomain && status.IsSign {
			log.Println("今天已经成功签到&不检查域名签到!")
			os.Exit(0)
		}
		if status.IsSign && status.IsQueryDomain {
			log.Println("今天已经成功签到并查询域名")
			os.Exit(0)
		}
	}

	formHash, cookie := login(*Username, *Password, *QuestionAnswer, *QuestionNum, &msg)
	if cookie == nil {
		msg = append(msg, "T00ls 登录失败！无法完成签到")
	} else {
		status = checkSign(cookie)
		if !status.IsSign {
			sign(formHash, cookie, &msg)
		}
		if *queryDomain {
			if status.IsQueryDomain {
				msg = append(msg, "今天已经查询过域名了！")
			} else {
				domainPool := []string{"chinaz", "ip138", "yooym"}
				for _, site := range domainPool {
					domains := getDomain(site)
					if len(domains) != 0 {
						msg = append(msg, fmt.Sprintf("%s 成功获取域名信息 %d 个", site, len(domains)))
						if queryDomainRs(formHash, cookie, domains, &msg, *Username) {
							break
						}
					} else {
						msg = append(msg, fmt.Sprintf("%s 获取域名信息失败！", site))
					}
				}
			}
		}

		status = checkSign(cookie)
		msg = append(msg, fmt.Sprintf("当前Tubi: %d", status.Core))
		outDate, _ := json.Marshal(status)
		wf, err := os.OpenFile(*flagPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600)
		if err != nil {
			msg = append(msg, err.Error())
		} else {
			_, _ = wf.Write(outDate)
			_ = wf.Close()
		}
	}

	if *secret == "" || *accessToken == "" {
		log.Println(strings.Join(msg, "\n"))
	} else {
		ding(strings.Join(msg, "\n"), *secret, *accessToken)
	}
}
